package service

import (
	"context"
	"database/sql"
	"fx_swift_boss/api"
	"fx_swift_boss/internal/model"
	"fx_swift_boss/pkg/code"
	"fx_swift_boss/pkg/global"
	"fx_swift_boss/pkg/internalerrors"
	"fx_swift_boss/pkg/logger"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/frame/g"
	"strconv"
)

type IFeeSrv interface {
	CreateMerchantFee(ctx context.Context, req *api.FeeReq) (string, error)
	QueryMerchantFeeDetails(ctx context.Context, req *api.FeeDetailsReq) (*api.FeeRes, error)
	DoFeeApproval(ctx context.Context, id, status string) error
	GetParentFeeDetails(ctx context.Context, agentAccount, feeType string) (*api.FeeRes, error)
}

type feeSrv struct {
}

func NewFeeSrv() IFeeSrv {
	return &feeSrv{}
}

// 查看上级手续费配置详情
func (f feeSrv) GetParentFeeDetails(ctx context.Context, agAccount, fType string) (*api.FeeRes, error) {
	var (
		err    error
		feeObj *api.FeeRes
	)
	//查询上级手续费
	feeType := "01"
	agentAccount := agAccount
	if fType == "01" {
		feeType = "03"
		agentAccount = ""
	}
	if fType == "00" && len(agentAccount) <= 0 {
		feeType = "03"
	}

	if err = global.GFDB.Schema("fx").Ctx(ctx).Model("ifcgate_fee").
		Where("agent_account=? and fee_type=? and status='1'", agentAccount, feeType).
		Scan(&feeObj); err != nil {
		logger.SugarLogger.Error(err)
		return nil, internalerrors.New(code.ErrUnknown, "查询数据异常")
	}
	if feeObj == nil {
		return nil, nil
	}

	return feeObj, nil
}

// 手续费审批下发
func (f feeSrv) DoFeeApproval(ctx context.Context, id, status string) error {
	var (
		err    error
		feeObj *model.IfcgateFee
	)
	if err = global.GFDB.Schema("fx").Model("ifcgate_fee").
		Where("id=?", id).Scan(&feeObj); err != nil {
		logger.SugarLogger.Error(err)
		return internalerrors.New(code.ErrUnknown, err.Error())
	}
	if feeObj == nil {
		return internalerrors.New(code.ErrUnknown, "记录不存在")
	}

	db := g.DB().Schema("fx")
	err = db.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		//先删除
		if status == "1" {
			if _, err := tx.Model("ifcgate_fee").
				Where("agent_account=? and account=? and merchant_no=? and status='1'", feeObj.AgentAccount, feeObj.Account, feeObj.MerchantNo).
				Delete(); err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "手续费状态修改失败")
			}
		}
		//修改手续费状态
		if _, err = tx.Model("ifcgate_fee").
			Data(g.Map{"status": status}).Where("id=?", id).
			Update(); err != nil {
			logger.SugarLogger.Error(err)
			return internalerrors.New(code.ErrUnknown, "更新异常")
		}
		return nil
	})

	return nil
}

// 查看手续费配置详情
func (f feeSrv) QueryMerchantFeeDetails(ctx context.Context, req *api.FeeDetailsReq) (*api.FeeRes, error) {
	var (
		err    error
		feeObj *api.FeeRes
	)

	if err = global.GFDB.Ctx(ctx).Schema("fx").Model("ifcgate_fee").
		Where("agent_account=? and account=? and merchant_no=? and fee_type=?", req.AgentAccount, req.EnterpriseAccount, req.MerchantNo, req.FeeType).
		OrderDesc("created_at").Limit(1).
		Scan(&feeObj); err != nil {
		logger.SugarLogger.Error(err)
		return nil, internalerrors.New(code.ErrUnknown, "查询数据异常")
	}
	if feeObj == nil {
		return nil, nil
	}

	return feeObj, nil
}

// 新增手续费配置
func (f feeSrv) CreateMerchantFee(ctx context.Context, req *api.FeeReq) (string, error) {
	var (
		err      error
		result   sql.Result
		rowsNums int64
		id       int64
		feeObj   *model.IfcgateFee
	)

	//查询上级手续费
	feeType := "01"
	agentAccount := req.AgentAccount
	if req.FeeType == "01" {
		feeType = "03"
		agentAccount = ""
	}
	if req.FeeType == "00" && len(req.AgentAccount) <= 0 {
		feeType = "03"
	}
	if err = global.GFDB.Ctx(ctx).Schema("fx").Model("ifcgate_fee").Where("agent_account=? and fee_type=? and status='1'", agentAccount, feeType).Scan(&feeObj); err != nil {
		logger.SugarLogger.Error(err)
		return "", internalerrors.New(code.ErrUnknown, "查询数据异常")
	}
	if feeObj == nil {
		return "", internalerrors.New(code.ErrUnknown, "上级手续费未配置")
	}
	//防止临界问题，比如当刚好进入修改页面，下级有企业已配置手续费
	if req.FeeType == "01" {
		feeNum, err := global.GFDB.Schema("fx").Model("ifcgate_fee").Where("agent_account=? and account !='' and fee_type='00'", req.AgentAccount).Count()
		if err != nil {
			logger.SugarLogger.Error(err)
			return "", internalerrors.New(code.ErrUnknown, "企业手续费查询数据异常")
		}
		if feeNum > 0 {
			return "", internalerrors.New(code.ErrUnknown, "下级企业已配置手续费，无法修改代理商手续费")
		}
	}

	//对手续费进行区间判断
	if req.GtCollectionFixedFee < feeObj.GtCollectionFixedFee {
		return "", internalerrors.New(code.ErrUnknown, "货贸(含电商)收款手续费固定部分不能低于"+strconv.FormatFloat(feeObj.GtCollectionFixedFee, 'f', -1, 64)+"USD")
	}
	if req.GtCollectionFee < feeObj.GtCollectionFee {
		return "", internalerrors.New(code.ErrUnknown, "货贸(含电商)收款手续费比例不能低于"+strconv.FormatFloat(feeObj.GtCollectionFee, 'f', -1, 64))
	}
	if req.GtPaymentFixedFee < feeObj.GtPaymentFixedFee {
		return "", internalerrors.New(code.ErrUnknown, "货贸(含电商)结汇手续费固定部分不能低于"+strconv.FormatFloat(feeObj.GtPaymentFixedFee, 'f', -1, 64)+"CNY")
	}
	if req.GtPaymentFee < feeObj.GtPaymentFee {
		return "", internalerrors.New(code.ErrUnknown, "货贸(含电商)结汇手续费比例不能低于"+strconv.FormatFloat(feeObj.GtPaymentFee, 'f', -1, 64))
	}
	if req.GtSpeedPaymentFixedFee < feeObj.GtSpeedPaymentFixedFee {
		return "", internalerrors.New(code.ErrUnknown, "货贸(含电商)极速结汇服务费固定部分不能低于"+strconv.FormatFloat(feeObj.GtSpeedPaymentFixedFee, 'f', -1, 64)+"CNY")
	}
	if req.GtSpeedPaymentFee < feeObj.GtSpeedPaymentFee {
		return "", internalerrors.New(code.ErrUnknown, "货贸(含电商)极速结汇服务费比例不能低于"+strconv.FormatFloat(feeObj.GtSpeedPaymentFee, 'f', -1, 64))
	}
	if req.StCollectionFixedFee < feeObj.StCollectionFixedFee {
		return "", internalerrors.New(code.ErrUnknown, "服贸收款手续费固定部分不能低于"+strconv.FormatFloat(feeObj.StCollectionFixedFee, 'f', -1, 64)+"USD")
	}
	if req.StCollectionFee < feeObj.StCollectionFee {
		return "", internalerrors.New(code.ErrUnknown, "服贸收款手续费比例不能低于"+strconv.FormatFloat(feeObj.StCollectionFee, 'f', -1, 64))
	}
	if req.StPaymentFixedFee < feeObj.StPaymentFixedFee {
		return "", internalerrors.New(code.ErrUnknown, "服贸结汇手续费固定部分不能低于"+strconv.FormatFloat(feeObj.StPaymentFixedFee, 'f', -1, 64)+"CNY")
	}
	if req.StPaymentFee < feeObj.StPaymentFee {
		return "", internalerrors.New(code.ErrUnknown, "服贸结汇手续费比例不能低于"+strconv.FormatFloat(feeObj.StCollectionFee, 'f', -1, 64))
	}
	if req.InternationalPaymentFixedFee < feeObj.InternationalPaymentFixedFee {
		return "", internalerrors.New(code.ErrUnknown, "国际swift付款-SHA手续费固定部分不能低于"+strconv.FormatFloat(feeObj.InternationalPaymentFixedFee, 'f', -1, 64)+"USD")
	}
	if req.InternationalPaymentFee < feeObj.InternationalPaymentFee {
		return "", internalerrors.New(code.ErrUnknown, "国际swift付款-SHA手续费比例不能低于"+strconv.FormatFloat(feeObj.InternationalPaymentFee, 'f', -1, 64))
	}
	if req.HkLocalPaymentFixedFee < feeObj.HkLocalPaymentFixedFee {
		return "", internalerrors.New(code.ErrUnknown, "香港local付款手续费固定部分不能低于"+strconv.FormatFloat(feeObj.HkLocalPaymentFixedFee, 'f', -1, 64)+"USD")
	}
	if req.HkLocalPaymentFee < feeObj.HkLocalPaymentFee {
		return "", internalerrors.New(code.ErrUnknown, "香港local手续费比例不能低于"+strconv.FormatFloat(feeObj.HkLocalPaymentFee, 'f', -1, 64))
	}
	if req.ExchangeRateDiff < feeObj.ExchangeRateDiff {
		return "", internalerrors.New(code.ErrUnknown, "换汇汇差比例不能低于"+strconv.FormatFloat(feeObj.ExchangeRateDiff, 'f', -1, 64))
	}

	//判断如果改条手续费是拒绝状态，则先删除原来的记录
	db := g.DB().Schema("fx")
	err = db.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		if req.Status == "2" {
			if _, err := tx.Model("ifcgate_fee").
				Where("agent_account=? and account=? and merchant_no=? and status='2'", req.AgentAccount, req.Account, req.MerchantNo).
				Delete(); err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "删除失败")
			}
		}

		//入库
		if result, err = tx.Insert("ifcgate_fee", &model.IfcgateFee{
			AgentAccount:                 req.AgentAccount,
			Account:                      req.Account,
			MerchantNo:                   req.MerchantNo,
			GtCollectionFixedFee:         req.GtCollectionFixedFee,
			GtCollectionFee:              req.GtCollectionFee,
			GtPaymentFixedFee:            req.GtPaymentFixedFee,
			GtPaymentFee:                 req.GtPaymentFee,
			GtSpeedPaymentFixedFee:       req.GtSpeedPaymentFixedFee,
			GtSpeedPaymentFee:            req.GtSpeedPaymentFee,
			StCollectionFixedFee:         req.StCollectionFixedFee,
			StCollectionFee:              req.StCollectionFee,
			StPaymentFixedFee:            req.StPaymentFixedFee,
			StPaymentFee:                 req.StPaymentFee,
			InternationalPaymentFixedFee: req.InternationalPaymentFixedFee,
			InternationalPaymentFee:      req.InternationalPaymentFee,
			InternationalPoboFixedFee:    req.InternationalPoboFixedFee,
			InternationalPoboFee:         req.InternationalPoboFee,
			HkLocalPaymentFixedFee:       req.HkLocalPaymentFixedFee,
			HkLocalPaymentFee:            req.HkLocalPaymentFee,
			ExchangeRateSource:           req.ExchangeRateSource,
			ExchangeRateDiff:             req.ExchangeRateDiff,
			RechargeExpensesFixedFee:     req.RechargeExpensesFixedFee,
			RechargeExpensesFee:          req.RechargeExpensesFee,
			AccountOpeningFixedFee:       req.AccountOpeningFixedFee,
			MonthlyMaintenanceFixedFee:   req.MonthlyMaintenanceFixedFee,
			FeeType:                      req.FeeType,
			Status:                       "0",
		}); err != nil {
			logger.SugarLogger.Error(err)
			return internalerrors.New(code.ErrUnknown, "手续费配置失败")
		}
		rowsNums, err = result.RowsAffected()
		if rowsNums == 0 {
			return internalerrors.New(code.ErrUnknown, "手续费配置失败")
		}
		id, err = result.LastInsertId()
		if id == 0 {
			return internalerrors.New(code.ErrUnknown, "手续费配置失败")
		}
		return nil
	})

	return strconv.FormatInt(id, 10), nil
}
